package dao;

import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import beans.HttpResultList;
import net.CommitJob;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class JobDao implements Serializable {

	private static final long serialVersionUID = -3197973251739895189L;

	public List<Object> getFullJobState(String taskHash, String blockId, String jobId){
		String sql ="";
		Object[] params = null;
		if(jobId==null){
			sql = "select * from history_job where task_hash=? and algorithm_hash=? and not ISNULL(isSuccess) ";
			params = new Object[]{taskHash, blockId};
		}else{
			sql = "select * from history_job where task_hash=? and algorithm_hash=? and job_id=?";
			params = new Object[]{taskHash, blockId, jobId};
		}
		List<Object> results = new ArrayList<>();
		return Query.executeQueryList(results, sql, params, new QueryCallBackList() {

			@Override
			public List<Object> doExecuteList(ResultSet rs, List<Object> results) {
				JSONArray resultt = new JSONArray();
				try {
					while(rs.next()){
						JSONObject result = new JSONObject();
						result.put("startInfo",rs.getString("start_info"));
						result.put("fullInfo",rs.getString("full_info"));
						resultt.add(result);
					}
					results.add(resultt);
				} catch (SQLException e) {
					e.printStackTrace();
				}
				return results;
			}
		});
	}
	public boolean insertJobState(CommitJob commitJob, String taskHash, String algorithmBlockId, String jobId, String algorithmId, String index, String jobName,String fullInfo){
		String sql = "insert into `history_job`(task_hash,algorithm_hash,job_id,algorithm_id,commit_time,start_time,name," +
				"command,full_info,start_info,job_index) values (?,?,?,?,now(),now(),?,?,?,?,?) ";
		String command = commitJob.getJhJobCommend();
		JSONObject startInfo = JSONObject.fromObject(commitJob);
		return Query.executeDML(sql, new Object[]{taskHash,algorithmBlockId,jobId,algorithmId,jobName,command,fullInfo,startInfo.toString(),index})>0;
	}

	/**
	 *
	 * @param status "DONE"  "EXIT" "PAUSE" "RUNNING" "STOP"
	 * @param subTaskHash
	 * @param algorithmHash
	 * @param jobId
	 * @return
	 */
	public boolean updateJobState(String status,String subTaskHash,String algorithmHash,String jobId) {
		String sql = "";
		Object[] params = null;
		if(status.equals("DONE")||status.equals("EXIT")||status.equals("STOP"))
		{
			sql = "update `history_job` set end_time=now(),isNew=1,isSuccess=?,name=?,full_info=? where task_hash=? and algorithm_hash=? and job_id=?";
			String jobName = jobId;
			String fullInfo = "";
			params = new Object[]{status,jobName,fullInfo,subTaskHash,algorithmHash,jobId};
		}else{
			String jobName = jobId;
			String fullInfo = "";
			sql = "update `history_job` set isSuccess=?,name=?,full_info=? where task_hash=? and algorithm_hash=? and job_id=?";
			params = new Object[]{status,jobName,fullInfo,subTaskHash,algorithmHash,jobId};
		}
		//2018-8-10添加：当计算那边返回作业的执行情况，需要去算法日志表格中更新一下
		SocketLogDao socketLogDao = new SocketLogDao();
		String algorithmState = socketLogDao.historyConvert2Log(status);
		socketLogDao.updateAlgorithmStateByJobId(algorithmState,jobId);
		return Query.executeDML(sql, params)>0;
	}

	/**
	 *
	 * @param status "DONE"  "EXIT" "PAUSE" "RUNNING"
	 * @param jobName
	 * @param fullInfo
	 * @param subTaskHash
	 * @param algorithmHash
	 * @param jobId
	 * @return
	 */
	public boolean updateJobState(String status,String jobName,String fullInfo, String subTaskHash,String algorithmHash,String jobId) {
		/*String sql = "update `history_job` set end_time=now(),isNew=1,reSend=1,isSuccess=?,name=?,full_info=? where task_hash=? and algorithm_hash=? and job_id=?";
		Object[] params = new Object[]{status,jobName,fullInfo,subTaskHash,algorithmHash,jobId};*/
		String sql = "update `history_job` set end_time=now(),isNew=1,reSend=1,isSuccess=?,name=?,full_info=? where job_id=?";
		Object[] params = new Object[]{status,jobName,fullInfo,jobId};
		return Query.executeDML(sql, params)>0;
	}

	//刷新正在运行中的作业状态
	public boolean updateRunningJobState(String status,String jobName,String fullInfo, String subTaskHash,String algorithmHash,String jobId) {
		String sql = "update `history_job` set isNew=1,isSuccess=?,name=?,full_info=? where task_hash=? and algorithm_hash=? and job_id=?";
		Object[] params = new Object[]{status,jobName,fullInfo,subTaskHash,algorithmHash,jobId};
		return Query.executeDML(sql, params)>0;
	}


	//查询作业是否结束
	public boolean getJobState(String subTaskHash,String algorithmHash,String jobId){
		String sql = "select !ISNULL(end_time) as finished from `history_job` where task_hash=? and algorithm_hash=? and job_id=?";
		return (boolean) Query.executeQueryObject(sql, new Object[]{subTaskHash,algorithmHash,jobId}, new QueryCallBack() {
			@Override
			public Object doExecute(ResultSet rs) {
				boolean bool = false;
				try {
					while(rs.next()){
						bool = rs.getBoolean("finished");
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
				return bool;
			}
		});
	}
	/**
	 * 用于前端动态显示作业状态
	 * @param subTaskHash
	 * @param isHistory
	 * @return
	 */
	public synchronized JSONArray getCompletedJobState(String subTaskHash, boolean isHistory) {
		String sql = "";
		if(isHistory){
			sql = "select * from `history_job` where task_hash=? and not ISNULL(isSuccess) order by end_time asc";
		}else{
			sql = "select * from `history_job` where task_hash=? order by end_time asc";
		}
		List<Object> results = new ArrayList<>();
		results = Query.executeQueryList(results, sql, new Object[]{subTaskHash}, new QueryCallBackList() {
			@Override
			public List<Object> doExecuteList(ResultSet rs, List<Object> results) {
				try {
					while(rs.next()){
						JSONObject oneJob = new JSONObject();
						oneJob.put("blockId", rs.getString("algorithm_hash"));
						oneJob.put("id", rs.getString("job_id"));
						oneJob.put("name", rs.getString("name"));
						oneJob.put("commitTime", rs.getString("commit_time"));
						oneJob.put("jobIndex", rs.getString("job_index"));
						String taskHash = rs.getString("task_hash");
						String algorithmHash = rs.getString("algorithm_hash");
						String isSuccess = rs.getString("isSuccess");
						String endTime = rs.getString("end_time");
						String full_info = rs.getString("full_info");
						oneJob.put("isSuccess", isSuccess==null ? "" : isSuccess);
						oneJob.put("endTime", endTime==null ? "" : endTime);
						oneJob.put("priority", JSONObject.fromObject(full_info).get("priority"));
						oneJob.put("isAlgorithmFinished", getAlgorithmState(taskHash,algorithmHash));
						results.add(oneJob);
					}
					return results;
				} catch (SQLException e) {
					e.printStackTrace();
					return results;
				}
			}
		});
		return JSONArray.fromObject(results);
	}

	/**
	 * 用于前端动态显示作业状态
	 * @param taskHash  对应的任务hash
	 * @param isHistory  是否需要显示改任务下所有的job
	 * @return
	 */
	public JSONArray getBatchTaskPackedJobState(String taskHash,boolean isHistory){
		HistoryTaskDao historyTaskDao = new HistoryTaskDao();
		HttpResultList subTaskHashes = historyTaskDao.getSubTaskHashByBatchTaskHash(taskHash);
		JSONArray resultArray = new JSONArray();
		for(Object subTaskHashObject:subTaskHashes.getDatas()){
			JSONObject result = new JSONObject();
			result.put("subTaskHash",subTaskHashObject);
			result.put("jobState",getCompletedJobState((String)subTaskHashObject,isHistory));
//			result.put("state",historyTaskDao.getSubTaskStatement((String)subTaskHashObject));
			resultArray.add(result);
		}
		return  resultArray;
	}

	private int getAlgorithmState(String taskHash, String algorithmHash) {
		String sql = "select end_time from `history_algorithm` where task_hash=? and algorithm_hash=?";
		String result = null;
		result = (String)Query.executeQueryObject(sql, new Object[]{taskHash, algorithmHash}, new QueryCallBack() {
			@Override
			public Object doExecute(ResultSet rs) {
				String result = null;
				try {
					while(rs.next()){
						result = rs.getString("end_time");
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
				return result;
			}
		});
		return result==null?0:1;
	}

	public List<Object> getFullAlgorithmState(String taskHash, String blockId) {
		String sql = "select * from history_algorithm where task_hash=? and algorithm_hash=?";
		List<Object> results = new ArrayList<>();
		return Query.executeQueryList(results, sql, new Object[]{taskHash, blockId}, new QueryCallBackList() {

			@Override
			public List<Object> doExecuteList(ResultSet rs, List<Object> results) {
				try {
					while(rs.next()){
						results.add(rs.getString("start_info"));
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
				return results;
			}
		});
	}

	//根据子任务hash查询作业id
	public List<Object> getJobIdByTaskHash(String subTaskHash){
		String sql = "select job_id from history_job where task_hash=?";
		List<Object> results = new ArrayList<>();
		return Query.executeQueryList(results,sql, new Object[]{subTaskHash}, new QueryCallBackList() {

			@Override
			public List<Object> doExecuteList(ResultSet rs,List<Object> results) {
				try {
					while(rs.next()){
						results.add(rs.getString("job_id"));
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
				return results;
			}
		});
	}

	//根据作业id更新作业名称和fullInfo
	public boolean updateJobNameAndFullInfo(String jobName, String fullInfo, String jobId) {
		String sql = "update `history_job` set name=?,full_info=? where job_id=?";
		Object[] params = new Object[]{jobName,fullInfo,jobId};
		return Query.executeDML(sql, params)>0;
	}

	//根据子任务hash查询作业详情
	public synchronized List<Object> getRunningJobState(String subTaskHash) {
		String sql = "select * from `history_job` where task_hash=?";
		List<Object> results = new ArrayList<>();
		return Query.executeQueryList(results, sql, new Object[]{subTaskHash}, new QueryCallBackList() {
			@Override
			public List<Object> doExecuteList(ResultSet rs, List<Object> results) {
				try {
					while(rs.next()){
						JSONObject oneJob = new JSONObject();
						oneJob.put("taskHash",rs.getString("task_hash"));
						oneJob.put("algorithmHash",rs.getString("algorithm_hash"));
						oneJob.put("jobId",rs.getString("job_id"));
						oneJob.put("algorithmId",rs.getString("algorithm_id"));
						oneJob.put("commitTime",rs.getString("commit_time"));
						oneJob.put("startTime",rs.getString("start_time"));
						oneJob.put("endTime",rs.getString("end_time"));
						oneJob.put("isSuccess",rs.getString("isSuccess"));
						oneJob.put("jobName",rs.getString("name"));
						oneJob.put("command",rs.getString("command"));
						oneJob.put("fullInfo",rs.getString("full_info"));
						oneJob.put("startInfo",rs.getString("start_info"));
						oneJob.put("jobIndex",rs.getString("job_index"));
						results.add(oneJob);
					}
					return results;
				} catch (SQLException e) {
					e.printStackTrace();
					return results;
				}
			}
		});
	}
}
